<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .box{width: 350px;position: relative;margin: 50px;}
    .m_box{width: 350px;height: 350px;}
    .m_box span{position: absolute;left:0;top:0;background: rgba(255,0,0,0.5);display: none;}

    .m_box em{position: absolute;z-index: 1;left:0;right:0;top:0;bottom:0;}

    .b_box{width: 350px;height: 350px;position: absolute;top: 0;left:360px;overflow: hidden;display: none;}
    .b_box img{position: absolute;left:0;top:0;}
  </style>
</head>
<body>
  <div class="box">
    <div class="m_box">
      <img src="../imgs/m0.jpg" alt="">
      <span></span>
      <em></em>
    </div>
    <div class="b_box">
      <img src="../imgs/l0.jpg" alt="">
    </div>
  </div>
</body>
<script>

  // OOA：放大镜（等比例移动）
  // 1. 获取元素【属性】
  // 2. 绑定事件【方法】
    // 3. 进入：显示遮罩层，右侧容器【方法】
    // 4. 离开：隐藏遮罩层，右侧容器【方法】
    // 5. 移动：【方法】
      // 6. 遮罩层跟随鼠标坐标
      // 7. 计算鼠标在左侧容器中移动的比例
      // 8. 根据比例计算右侧图片要移动的距离

  // OOD：
  // function BigImg(){
  //   // 获取元素
  //   this.addEvent()
  // }
  // BigImg.prototype.addEvent = function(){
  //   // 进入
  //     this.show()
  //   // 离开
  //     this.hide()
  //   // 移动
  //     this.move()
  // }
  // BigImg.prototype.show = function(){
  //   // 显示
  // }
  // BigImg.prototype.hide = function(){
  //   // 隐藏
  // }
  // BigImg.prototype.move = function(){
  //   // 移动
  //   // 比例
  // }
  // new BigImg({})


  // OOP：
  function BigImg( {mBox, mSpan, bBox, bImg} ){
    // 获取元素
    this.mBox = mBox;
    this.mSpan = mSpan;
    this.bBox = bBox;
    this.bImg = bImg;

    // 绑定事件
    this.addEvent()
  }
  BigImg.prototype.addEvent = function(){
    const that = this;
    // 进入
    this.mBox.onmouseover = function(){
      that.show()
    }
    // 离开
    this.mBox.onmouseout = function(){
      that.hide()
    }
    // 移动
    this.mBox.onmousemove = function(eve){
      const e = eve || window.event;
      that.move( e );
    }
  }
  BigImg.prototype.show = function(){
    // 显示
    this.mSpan.style.display = "block";
    this.bBox.style.display = "block";

    // 为了方便，提前获取各个元素的各个尺寸
    this.bBoxW = this.bBox.offsetWidth;
    this.bBoxH = this.bBox.offsetHeight;
    this.bImgW = this.bImg.offsetWidth;
    this.bImgH = this.bImg.offsetHeight;
    this.mBoxW = this.mBox.offsetWidth;
    this.mBoxH = this.mBox.offsetHeight;
    // 根据右侧容器显示的图片区域的比例，计算左侧遮罩层的尺寸
    this.mSpanW = this.bBoxW / this.bImgW * this.mBoxW;
    this.mSpanH = this.bBoxH / this.bImgH * this.mBoxH;
    // 设置给遮罩层
    this.mSpan.style.width = this.mSpanW + "px";
    this.mSpan.style.height = this.mSpanH + "px";
  }
  BigImg.prototype.hide = function(){
    // 隐藏
    this.mSpan.style.display = "none";
    this.bBox.style.display = "none";
  }
  BigImg.prototype.move = function(e){
    // 计算要设置给遮罩层的距离
    let l = e.offsetX - this.mSpanW / 2;
    let t = e.offsetY - this.mSpanH / 2;
    // 边界限定
    if(l < 0) l = 0;
    if(t < 0) t = 0;
    if( l > this.mBoxW - this.mSpanW ){
      l = this.mBoxW - this.mSpanW
    }
    if( t > this.mBoxH - this.mSpanH ){
      t = this.mBoxH - this.mSpanH
    }
    // 设置给遮罩层
    this.mSpan.style.left = l + "px";
    this.mSpan.style.top = t + "px";
    // 根据遮罩层移动的距离，计算比例
    const x = l / (this.mBoxW - this.mSpanW);
    const y = t / (this.mBoxH - this.mSpanH);
    // 根据遮罩层移动的比例，计算右侧图片要移动的距离
    this.bImg.style.left = -(this.bImgW - this.bBoxW) * x + "px"; 
    this.bImg.style.top = -(this.bImgH - this.bBoxH) * y + "px"; 
  }



  new BigImg({
    mBox: document.querySelector(".m_box"),
    mSpan: document.querySelector(".m_box span"),
    bBox: document.querySelector(".b_box"),
    bImg: document.querySelector(".b_box img")
  })



  
</script>
</html>